﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CommonLib.CacheOperation
{
    /// <summary>
    /// 自动更新的缓存
    /// </summary>
    public static class AutoUpdateCache
    {
        private static Dictionary<string, AutoUpdateItem> _dicCache = new Dictionary<string, AutoUpdateItem>();
        private static object _locker = new object();

        public static void Add(string key, AutoUpdateItem autoUpdateItem)
        {
            if (!_dicCache.ContainsKey(key))
            {
                lock (_locker)
                {
                    if (!_dicCache.ContainsKey(key))
                    {
                        _dicCache.Add(key, autoUpdateItem);
                    }
                }
            }
        }

        public static void Remove(string key)
        {
            _dicCache.Remove(key);
        }

        public static T GetValue<T>(string key)
            where T : class
        {
            if (!_dicCache.ContainsKey(key))
            {
                throw new ArgumentException("AutoUpdateCache - 不存在的Key:" + key);
            }

            if (_dicCache[key].ExpiredTime < DateTime.Now)
            {
                lock (_locker)
                {
                    if (_dicCache[key].ExpiredTime < DateTime.Now)
                    {
                        _dicCache[key].UpdateValue(_dicCache[key]);
                        _dicCache[key].UpdateExpiredTime();
                    }
                }
            }

            return _dicCache[key].Value as T;
        }
    }

    public class AutoUpdateItem
    {
        public object Value { get; set; }

        public Action<AutoUpdateItem> UpdateValue;

        public DateTime ExpiredTime { get; private set; }

        private int _expiredSeconds = 0;

        public int ExpiredSeconds
        {
            get { return _expiredSeconds; }
            set
            {
                _expiredSeconds = value;
                this.ExpiredTime = DateTime.Now.AddSeconds(_expiredSeconds);
            }
        }

        public void UpdateExpiredTime()
        {
            this.ExpiredTime = DateTime.Now.AddSeconds(_expiredSeconds);
        }
    }
}
